﻿package util;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import javax.mail.BodyPart;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;

public class ReceiveMail {
	/**
	 * 
	 * 参考资料：http://xiangzhengyan.iteye.com/blog/85961
	 * */
	private String pop3Server;  //POP3服务器地址
	private String protocal;  //协议
	private String username;  //登录SMTP服务器的用户名
	private String password;  //登录SMTP服务器的密码
	
	public ReceiveMail(){
		
	}
		
	public ReceiveMail(String pop3Server,String protocal,String username,String password){
		this.pop3Server = pop3Server;
		this.protocal = protocal;
		this.username = username;
		this.password = password;
	}
	
	public void setPop3Server(String pop3Server) {
		this.pop3Server = pop3Server;
	}

	public void setProtocal(String protocal) {
		this.protocal = protocal;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	//获取邮件
	public void receiveAllMail(){
        // 创建一个有具体连接信息的Properties对象  
		Properties properties = new Properties();
		properties.put("mail.store.protocal", protocal);
		properties.put("mail.pop3.host", pop3Server);		
		
		// 使用Properties对象获得Session对象  
		Session session = Session.getInstance(properties);
		session.setDebug(false);
		
		// 利用Session对象获得Store对象，并连接pop3服务器 		 
		try {
			Store store = session.getStore(protocal);
			store.connect(pop3Server,username, password);
			
			//获取收件箱  
			Folder folder = store.getFolder("INBOX");
			folder.open(Folder.READ_ONLY);  //以只读权限打开收件箱  
			/**
			 * Folder.READ_ONLY：表示只读权限。
			 *  Folder.READ_WRITE：表示可以修改并读取邮件夹中的邮件。
			 *  */
			
			//获取收件箱中的邮件
			Message[] messages = folder.getMessages();
			System.out.println("总的邮件数目："+messages.length);
			System.out.println("新邮件数目："+folder.getNewMessageCount());
			System.out.println("未读邮件数目："+folder.getUnreadMessageCount());
			
			for(int i=0;i<messages.length;i++){
				HandleReceivedMail handleOneMail = new HandleReceivedMail((MimeMessage) messages[i]);
				System.out.println("Message "+ i + " : 主题："+handleOneMail.getSubject());
				System.out.println("Message "+ i + " : 时间："+handleOneMail.getSendDate());
				System.out.println("Message "+ i + " : 发件人："+handleOneMail.getFrom());
//				System.out.println("Message "+ i + " : Message-ID："+handleOneMail.getMessageID());
				System.out.println("Message "+ i + " : 回执："+handleOneMail.getReplySign());
				handleOneMail.getMailContent((Part)messages[i]);
				System.out.println("Message "+ i + " : 正文："+handleOneMail.getBodyText());
				System.out.println("Message "+ i + " : 附件："+handleOneMail.isContainAttach((Part)messages[i]));
				System.out.println();
			}
			
			//关闭连接
			folder.close(false);
			store.close();
		} catch (Exception e) {
			System.out.println("连接POP3服务器失败");
			e.printStackTrace();
		}
		
		
	}
	
	public static void main(String[] args) {
		ReceiveMail receiveMail = new ReceiveMail("pop3.163.com","pop3","zifangsky@163.com","******");
//		ReceiveMail receiveMail = new ReceiveMail("pop.qq.com","pop3","983836259@qq.com","******");
		receiveMail.receiveAllMail();
	}

}

/**
 * 对获取到的邮件进行解析，提取出：主题，正文，附件等内容
 * */
class HandleReceivedMail{
	private MimeMessage mimeMessage = null;
	private StringBuffer bodytext = new StringBuffer();//存放邮件内容   
	
	public HandleReceivedMail(MimeMessage mimeMessage){
		this.mimeMessage = mimeMessage;
	}
	
	//进行解密，防止中文乱码
	public String changeEncode(String str){
		try {
			 if (str == null || "".equals(str)) 
		         str = ""; 
			 else
				 str = MimeUtility.decodeText(str); 
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return str;
	}
	
	//获取邮件主题
	public String getSubject(){
		String subject = "";
		try {
			subject = changeEncode(mimeMessage.getSubject());
			if(subject == null)
				subject = "";	
			return subject;
		} catch (MessagingException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	//获取邮件发送时间
	public String getSendDate(){
		try {
			Date sendDate = mimeMessage.getSentDate();
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			return dateFormat.format(sendDate);
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	//获取发件人姓名和地址
	public String getFrom(){
		try {
			InternetAddress[] address = (InternetAddress[]) mimeMessage.getFrom();
			String person = address[0].getPersonal();  //姓名
			if(person == null)
				person = "";
			String from = address[0].getAddress();  //地址
			if(from == null)
				from = "";
			return person+"["+from+"]";
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
	
	//获取邮件的Message-ID
	public String getMessageID(){
		try {
			return mimeMessage.getMessageID();
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
	//判断邮件是否需要回执，需要返回“true”，否则返回“false”
	public boolean getReplySign(){
		try {
			String[] reply = mimeMessage.getHeader("Disposition-Notification-To");
			if(reply != null)
				return true;	
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;	
	}	
	
	//正文文本内容
	public String getBodyText(){
		return bodytext.toString();
	}
	
	//解析邮件
	public void getMailContent(Part part){
		try {
			String contentType = part.getContentType();
			int nameIndex = contentType.indexOf("name");
			boolean isContainTextAttach = false;  //判断邮件中是否含有嵌套体
			if(nameIndex != -1)
				isContainTextAttach = true;
			if(part.isMimeType("text/plain") && !isContainTextAttach)
				bodytext.append((String)part.getContent());
			else if(part.isMimeType("text/html") && !isContainTextAttach)
				bodytext.append((String)part.getContent());  //对于HTML格式邮件，可以在前后加上标签<html><head>subject</head><body>bodytext</body></html>，保存为html格式文件（PS：未写）
			else if(part.isMimeType("message/rfc822"))
				getMailContent((Part) part.getContent());
			else if(part.isMimeType("multipart/*")){
				Multipart multipart = (Multipart) part.getContent();
				int count = multipart.getCount();
				for(int i=0;i<count;i++)
					getMailContent(multipart.getBodyPart(i));
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}
	
	//判断是否包含附件
	public boolean isContainAttach(Part part){
		boolean attachflag = false;  //是否有附件
		try {
			String contentType = part.getContentType();
			if(part.isMimeType("multipart/*")){
				Multipart multipart = (Multipart) part.getContent();
				for(int i=0;i<multipart.getCount();i++){
					BodyPart bodyPart = multipart.getBodyPart(i);
					String disposition = bodyPart.getDisposition();
					if((disposition != null) && (disposition.equals(Part.ATTACHMENT) || disposition.equals(Part.INLINE)))
						attachflag = true;
					else if(bodyPart.isMimeType("multipart/*"))
						attachflag = isContainAttach((Part)bodyPart);
					else{
						String bodytype = bodyPart.getContentType();
						if(bodytype.toLowerCase().indexOf("application") !=-1)
							attachflag = true;
						if(bodytype.toLowerCase().indexOf("name") !=-1)
							attachflag = true;
					}
					
				}
			}
			else if(part.isMimeType("message/rfc822"))
				attachflag = isContainAttach((Part)part.getContent());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		return attachflag;	
	}
	
	//保存附件
	//以后再写
	
	
}
